Completed
Push — master ( 4bb4df...375c4e )
by Sander
10s
created

angular.controller(ꞌCredentialCtrlꞌ)   C

Complexity

Conditions 8
Paths 16

Size

Total Lines 376

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 8
nc 16
nop 19
dl 0
loc 376
rs 5.2676
c 2
b 0
f 0

How to fix   Long Method    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
/**
2
 * Nextcloud - passman
3
 *
4
 * @copyright Copyright (c) 2016, Sander Brand ([email protected])
5
 * @copyright Copyright (c) 2016, Marcos Zuriaga Miguel ([email protected])
6
 * @license GNU AGPL version 3 or any later version
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License as
10
 * published by the Free Software Foundation, either version 3 of the
11
 * License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
23
(function () {
24
	'use strict';
25
26
27
	/**
28
	 * @ngdoc function
29
	 * @name passmanApp.controller:MainCtrl
30
	 * @description
31
	 * # MainCtrl
32
	 * Controller of the passmanApp
33
	 */
34
	angular.module('passmanApp')
35
		.controller('CredentialCtrl', ['$scope', 'VaultService', 'SettingsService', '$location', 'CredentialService',
36
			'$rootScope', 'FileService', 'EncryptService', 'TagService', '$timeout', 'NotificationService', 'CacheService', 'ShareService', 'SharingACL', '$interval', '$filter', '$routeParams', '$sce', '$translate',
37
			function ($scope, VaultService, SettingsService, $location, CredentialService, $rootScope, FileService, EncryptService, TagService, $timeout, NotificationService, CacheService, ShareService, SharingACL, $interval, $filter, $routeParams, $sce, $translate) {
38
				$scope.active_vault = VaultService.getActiveVault();
39
				if (!SettingsService.getSetting('defaultVault') || !SettingsService.getSetting('defaultVaultPass')) {
40
					if (!$scope.active_vault) {
41
						$location.path('/');
42
					}
43
				} else {
44
					if (SettingsService.getSetting('defaultVault') && SettingsService.getSetting('defaultVaultPass')) {
45
						var _vault = angular.copy(SettingsService.getSetting('defaultVault'));
46
						_vault.vaultKey = angular.copy(SettingsService.getSetting('defaultVaultPass'));
47
						VaultService.setActiveVault(_vault);
48
						$scope.active_vault = _vault;
49
						//@TODO check if vault exists
50
					}
51
				}
52
53
				$scope.show_spinner = true;
54
				var fetchCredentials = function () {
55
					VaultService.getVault({guid: $routeParams.vault_id}).then(function (vault) {
56
						var vaultKey = angular.copy($scope.active_vault.vaultKey);
57
						var _credentials = angular.copy(vault.credentials);
58
						vault.credentials = [];
59
						$scope.active_vault = vault;
60
						$scope.active_vault.vaultKey = vaultKey;
61
						VaultService.setActiveVault($scope.active_vault);
62
						for (var i = 0; i < _credentials.length; i++) {
63
							var _credential = _credentials[i];
64
							try {
65
								if (!_credential.shared_key) {
66
									_credential = CredentialService.decryptCredential(angular.copy(_credential));
67
68
								} else {
69
									var enc_key = EncryptService.decryptString(_credential.shared_key);
70
									_credential = ShareService.decryptSharedCredential(angular.copy(_credential), enc_key);
71
								}
72
								_credential.tags_raw = _credential.tags;
73
							} catch (e) {
74
75
								NotificationService.showNotification($translate.instant('error.decrypt'), 5000);
76
								//$rootScope.$broadcast('logout');
77
								//SettingsService.setSetting('defaultVaultPass', null);
78
								//.setSetting('defaultVault', null);
79
								//$location.path('/')
80
81
							}
82
							_credentials[i] = _credential;
83
						}
84
85
						ShareService.getCredendialsSharedWithUs(vault.guid).then(function (shared_credentials) {
86
							for (var c = 0; c < shared_credentials.length; c++) {
87
								var _shared_credential = shared_credentials[c];
88
								var decrypted_key = EncryptService.decryptString(_shared_credential.shared_key);
89
								var _shared_credential_data;
90
								try {
91
									_shared_credential_data = ShareService.decryptSharedCredential(_shared_credential.credential_data, decrypted_key);
92
								} catch (e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
93
94
								}
95
								if (_shared_credential_data) {
96
									delete _shared_credential.credential_data;
97
									_shared_credential_data.acl = _shared_credential;
98
									_shared_credential_data.acl.permissions = new SharingACL(_shared_credential_data.acl.permissions);
99
									_shared_credential_data.tags_raw = _shared_credential_data.tags;
100
									_credentials.push(_shared_credential_data);
101
								}
102
							}
103
							angular.merge($scope.active_vault.credentials, _credentials);
104
							$scope.show_spinner = false;
105
							$rootScope.$broadcast('credentials_loaded');
106
							if(!vault.private_sharing_key){
107
								var key_size = 1024;
108
								ShareService.generateRSAKeys(key_size).then(function (kp) {
109
									var pem = ShareService.rsaKeyPairToPEM(kp);
110
									$scope.creating_keys = false;
111
									$scope.active_vault.private_sharing_key = pem.privateKey;
112
									$scope.active_vault.public_sharing_key = pem.publicKey;
113
									$scope.$digest();
114
									VaultService.updateSharingKeys($scope.active_vault);
115
								});
116
							}
117
						});
118
					});
119
				};
120
121
				var getPendingShareRequests = function () {
122
					ShareService.getPendingRequests().then(function (shareRequests) {
123
						if (shareRequests.length > 0) {
124
							$scope.incoming_share_requests = shareRequests;
125
							jQuery('.share_popup').dialog({
126
								width: 600,
127
								position: ['center', 90]
128
							});
129
						}
130
					});
131
				};
132
133
134
135
				var refresh_data_interval = null;
136
				if ($scope.active_vault) {
137
					$scope.$parent.selectedVault = true;
138
					fetchCredentials();
139
					getPendingShareRequests();
140
					refresh_data_interval = $interval(function () {
141
						fetchCredentials();
142
						getPendingShareRequests();
143
					}, 60000 * 5);
144
				}
145
				$scope.$on('$destroy', function () {
146
					$interval.cancel(refresh_data_interval);
147
				});
148
149
150
				$scope.permissions = new SharingACL(0);
151
152
				$scope.hasPermission = function (acl, permission) {
153
					if (acl) {
154
						var tmp = new SharingACL(acl.permission);
155
						return tmp.hasPermission(permission);
156
					} else {
157
						return true;
158
					}
159
160
				};
161
162
				$scope.acceptShareRequest = function (share_request) {
163
					var crypted_shared_key = share_request.shared_key;
164
					var private_key = EncryptService.decryptString(VaultService.getActiveVault().private_sharing_key);
165
166
					private_key = ShareService.rsaPrivateKeyFromPEM(private_key);
167
					/** global: forge */
168
					crypted_shared_key = private_key.decrypt(forge.util.decode64(crypted_shared_key));
169
					crypted_shared_key = EncryptService.encryptString(crypted_shared_key);
170
171
					ShareService.saveSharingRequest(share_request, crypted_shared_key).then(function () {
172
						var idx = $scope.incoming_share_requests.indexOf(share_request);
173
						$scope.incoming_share_requests.splice(idx, 1);
174
						var active_share_requests = false;
175
						for (var v = 0; v < $scope.incoming_share_requests.length; v++) {
176
							if ($scope.incoming_share_requests[v].target_vault_id === $scope.active_vault.vault_id) {
177
								active_share_requests = true;
178
							}
179
						}
180
						if (active_share_requests === false) {
181
							jQuery('.ui-dialog').remove();
182
							fetchCredentials();
183
						}
184
					});
185
				};
186
187
				$scope.declineShareRequest = function (share_request) {
188
					ShareService.declineSharingRequest(share_request).then(function () {
189
						var idx = $scope.incoming_share_requests.indexOf(share_request);
190
						$scope.incoming_share_requests.splice(idx, 1);
191
						var active_share_requests = false;
192
						for (var v = 0; v < $scope.incoming_share_requests.length; v++) {
193
							if ($scope.incoming_share_requests[v].target_vault_id === $scope.active_vault.vault_id) {
194
								active_share_requests = true;
195
							}
196
						}
197
						if (active_share_requests === false) {
198
							jQuery('.ui-dialog').remove();
199
							fetchCredentials();
200
						}
201
					});
202
				};
203
204
205
206
				var settingsLoaded = function () {
207
					$scope.settings = SettingsService.getSettings();
208
				};
209
210
				if(!SettingsService.getSetting('settings_loaded')){
211
					$rootScope.$on('settings_loaded', function () {
212
						settingsLoaded();
213
					});
214
				} else {
215
					settingsLoaded();
216
				}
217
218
219
				$scope.addCredential = function () {
220
					var new_credential = CredentialService.newCredential();
221
					var enc_c = CredentialService.encryptCredential(new_credential);
222
					SettingsService.setSetting('edit_credential', enc_c);
223
					$location.path('/vault/' + $scope.active_vault.guid + '/new');
224
				};
225
226
				$scope.editCredential = function (credential) {
227
					var _credential = angular.copy(credential);
228
					$rootScope.$emit('app_menu', false);
229
					SettingsService.setSetting('edit_credential', CredentialService.encryptCredential(_credential));
230
					$location.path('/vault/' + $scope.active_vault.guid + '/edit/' + _credential.guid);
231
				};
232
233
				$scope.getRevisions = function (credential) {
234
					var _credential = angular.copy(credential);
235
					$rootScope.$emit('app_menu', false);
236
					SettingsService.setSetting('revision_credential', CredentialService.encryptCredential(_credential));
237
					$location.path('/vault/' + $scope.active_vault.guid + '/' + _credential.guid + '/revisions');
238
				};
239
240
				$scope.shareCredential = function (credential) {
241
					var _credential = angular.copy(credential);
242
					$rootScope.$emit('app_menu', false);
243
					SettingsService.setSetting('share_credential', CredentialService.encryptCredential(_credential));
244
					$location.path('/vault/' + $scope.active_vault.guid + '/' + _credential.guid + '/share');
245
				};
246
247
				var notification;
248
				$scope.deleteCredential = function (credential) {
249
					var _credential = angular.copy(credential);
250
					try {
251
						_credential = CredentialService.decryptCredential(_credential);
252
					} catch (e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
253
254
					}
255
					_credential.delete_time = new Date().getTime() / 1000;
256
					for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
257
						if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
258
							$scope.active_vault.credentials[i].delete_time = _credential.delete_time;
259
						}
260
					}
261
					$scope.closeSelected();
262
					if (notification) {
263
						NotificationService.hideNotification(notification);
264
					}
265
					var key = CredentialService.getSharedKeyFromCredential(_credential);
266
					CredentialService.updateCredential(_credential, false, key).then(function () {
267
						notification = NotificationService.showNotification($translate.instant('credential.deleted'), 5000);
268
					});
269
				};
270
271
				$scope.recoverCredential = function (credential) {
272
					var _credential = angular.copy(credential);
273
					try {
274
						_credential = CredentialService.decryptCredential(_credential);
275
					} catch (e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
276
277
					}
278
					for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
279
						if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
280
							$scope.active_vault.credentials[i].delete_time = 0;
281
						}
282
					}
283
					_credential.delete_time = 0;
284
					$scope.closeSelected();
285
					if (notification) {
286
						NotificationService.hideNotification(notification);
287
					}
288
					var key = CredentialService.getSharedKeyFromCredential(_credential);
289
					CredentialService.updateCredential(_credential, false, key).then(function () {
290
						NotificationService.showNotification($translate.instant('credential.recovered'), 5000);
291
					});
292
				};
293
294
				$scope.destroyCredential = function (credential) {
295
					var _credential = angular.copy(credential);
296
					CredentialService.destroyCredential(_credential.guid).then(function () {
297
						for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
298
							if ($scope.active_vault.credentials[i].credential_id === credential.credential_id) {
299
								$scope.active_vault.credentials.splice(i, 1);
300
								NotificationService.showNotification($translate.instant('credential.destroyed'), 5000);
301
								break;
302
							}
303
						}
304
					});
305
				};
306
307
				$scope.view_mode = 'list'; //@TODO make this a setting
308
				$scope.switchViewMode = function (viewMode) {
309
					$scope.view_mode = viewMode;
310
				};
311
312
				$scope.filterOptions = {
313
					filterText: '',
314
					fields: ['label', 'username', 'email', 'custom_fields']
315
				};
316
317
318
				$scope.filtered_credentials = [];
319
				$scope.$watch('[selectedtags, filterOptions, delete_time, active_vault.credentials]', function () {
320
					if (!$scope.active_vault) {
321
						return;
322
					}
323
					if ($scope.active_vault.credentials) {
324
						var credentials = angular.copy($scope.active_vault.credentials);
325
						var filtered_credentials = $filter('credentialSearch')(credentials, $scope.filterOptions);
326
						filtered_credentials = $filter('tagFilter')(filtered_credentials, $scope.selectedtags);
327
						filtered_credentials = $filter('filter')(filtered_credentials, {hidden: 0});
328
						$scope.filtered_credentials = filtered_credentials;
329
						$scope.filterOptions.selectedtags = angular.copy($scope.selectedtags);
330
						for (var i = 0; i < $scope.active_vault.credentials.length; i++) {
331
							var _credential = $scope.active_vault.credentials[i];
332
							if (_credential.tags) {
333
								TagService.addTags(_credential.tags);
334
							}
335
						}
336
					}
337
338
				}, true);
339
340
				$scope.selectedtags = [];
341
				var to;
342
				$rootScope.$on('selected_tags_updated', function (evt, _sTags) {
343
					var _selectedTags = [];
344
					for (var x = 0; x < _sTags.length; x++) {
345
						_selectedTags.push(_sTags[x].text);
346
					}
347
					$scope.selectedtags = _selectedTags;
348
					$timeout.cancel(to);
349
					if (_selectedTags.length > 0) {
350
						to = $timeout(function () {
351
							if ($scope.filtered_credentials) {
352
								var _filtered_tags = [];
353
								for (var i = 0; i < $scope.filtered_credentials.length; i++) {
354
									var tags = $scope.filtered_credentials[i].tags_raw;
355
									for (var x = 0; x < tags.length; x++) {
356
										var tag = tags[x].text;
357
										if (_filtered_tags.indexOf(tag) === -1) {
358
											_filtered_tags.push(tag);
359
										}
360
									}
361
								}
362
363
								$rootScope.$emit('limit_tags_in_list', _filtered_tags);
364
							}
365
						}, 50);
366
					}
367
				});
368
369
				$scope.delete_time = 0;
370
				$scope.showCredentialRow = function (credential) {
371
					if ($scope.delete_time === 0) {
372
						return credential.delete_time === 0;
373
					} else {
374
						return credential.delete_time > $scope.delete_time;
375
					}
376
377
				};
378
379
				$rootScope.$on('set_delete_time', function (event, time) {
380
					$scope.delete_time = time;
381
				});
382
383
				$scope.setDeleteTime = function (delete_time) {
384
					$scope.delete_time = delete_time;
385
				};
386
387
				$scope.selectedCredential = false;
388
				$scope.selectCredential = function (credential) {
389
					if(credential.description) {
390
						credential.description_html = $sce.trustAsHtml(angular.copy(credential.description).replace("\n", '<br />'));
391
					}
392
					$scope.selectedCredential = angular.copy(credential);
393
					$rootScope.$emit('app_menu', true);
394
				};
395
396
				$scope.closeSelected = function () {
397
					$rootScope.$emit('app_menu', false);
398
					$scope.selectedCredential = false;
399
				};
400
401
				$rootScope.$on('logout', function () {
402
					$scope.active_vault = null;
403
					$scope.credentials = [];
404
//				$scope.$parent.selectedVault = false;
405
406
				});
407
408
				$scope.clearState = function () {
409
					$scope.delete_time = 0;
410
				};
411
412
			}]);
413
}());